#
#Copyright (c) 2024 Black Sesame Technologies
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
#


include config.mk

CYGWIN_PWD := $(shell pwd)

# ��Cygwin·��ת��ΪWindows·��
#WINDOWS_PWD := $(shell cygpath -w $(CYGWIN_PWD))

# ��Windows·��ת��ΪCygwin·��
#CYGWIN_OUTPUT_PATH := $(shell cygpath -m $(WINDOWS_PWD))

#TOP_DIR := $(CYGWIN_OUTPUT_PATH)

TOP_DIR := $(PWD)
OBJ_DIR := $(TOP_DIR)/$(BUILD_DIR)/OBJ
OUT_DIR := $(TOP_DIR)/$(BUILD_DIR)
ELF_DIR := $(OBJ_DIR)

ELF_FILE := ut_zebu
ELF_FILE := $(join $(ELF_FILE),.elf)
ELF_FILE := $(subst module_,,$(ELF_FILE))
#LIBPATH  := -L /usr/local/arm/4.4.3/lib/gcc/arm-none-linux-gnueabi/4.4.3 -lgcc
#LIBPATH  := -L /usr/opt/gcc-arm-none-eabi-8-2018-q4-major/lib/gcc/arm-none-eabi/8.2.1/ -lgcc

ifneq ("$(filter ARM9  R5,$(ARCH))", "")
  CC := arm-linux-gcc
  LD := arm-linux-ld
  AR := arm-linux-ar
  OBJCOPY := arm-linux-objcopy
  OBJDUMP := arm-linux-objdump
  READELF := arm-linux-readelf

  INCLUDE_DIRS = $(TOP_DIR)/include \
			   $(TOP_DIR)/arch/$(ARCH)/include \
			   $(TOP_DIR)/include/library
  CFLAGS 	:= -Wall -Wstrict-prototypes -$(OLEVEL) -fomit-frame-pointer -ffreestanding -fno-builtin -fno-strict-aliasing
  CPPFLAGS = -nostdinc $(INCLUDE_DIRS) -nostdinc
  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif

ifneq ("$(filter M0,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS 	:= -nostartfiles -fno-builtin -g -O0 -mthumb -mcpu=cortex-m0
  CPPFLAGS =
  LIBPATH  := -L $(TOP_DIR)/library/ -lgccv6m
endif

ifneq ("$(filter R5_SECURE,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS 	:= -g -O1 -Wall -fdata-sections -mcpu=cortex-r5
  CPPFLAGS =
  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc

  CFLAGS += -DSECURE_CPU
  CFLAGS += -DR5_SECURE
endif

ifneq ("$(filter R5_SAFETY,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS 	:= -nostartfiles -fno-builtin -g -O0 -mcpu=cortex-r5
  CPPFLAGS =
  CFLAGS += -DR5_SAFETY

  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif

ifneq ("$(filter R5_REALTIME,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS 	:= -nostartfiles -fno-builtin -g -O1 -mcpu=cortex-r5
  CPPFLAGS =
  CFLAGS += -DR5_REALTIME

  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif

ifneq ("$(filter R5_SWITCH,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS        := -nostartfiles -fno-builtin -g -O1 -mcpu=cortex-r5
  CPPFLAGS =
  CFLAGS += -DR5_SWITCH

  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif


ifneq ("$(filter R5_SWITCH_CPU0,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf
    
  CFLAGS        := -nostartfiles -fno-builtin -g -O1 -mcpu=cortex-r5
  CPPFLAGS = 
  CFLAGS += -DR5_SWITCH_CPU0

  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif

ifneq ("$(filter R5_SWITCH_CPU1,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf
    
  CFLAGS        := -nostartfiles -fno-builtin -g -O1 -mcpu=cortex-r5
  CPPFLAGS = 
  CFLAGS += -DR5_SWITCH_CPU1

  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif

ifneq ("$(filter R5_SWITCH_CPU2,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-gcc
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf
    
  CFLAGS := -nostartfiles -fno-builtin -g -O2 -mcpu=cortex-r5

  GCCFLAGS = -mcpu=cortex-r5 -O1 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3
  LDFLAGS	= $(CFLAGS) -nostartfiles -Xlinker --gc-sections --specs=nano.specs -u _printf_float --specs=nosys.specs \
  						-Xlinker -Map=output.map -Xlinker --print-gc-sections

  CPPFLAGS = 
  CFLAGS += -DR5_SWITCH_CPU2
  # CFLAGS += -DUART_DEBUG_RT2

endif

ifneq ("$(filter R5_SOC,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS        := -nostartfiles -fno-builtin -g -O1 -mcpu=cortex-r5
  CPPFLAGS =
  CFLAGS += -DR5_SOC

  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif

ifneq ("$(filter R5,$(ARCH))", "")
  CC := arm-none-eabi-gcc
  LD := arm-none-eabi-ld
  AR := arm-none-eabi-ar
  OBJCOPY := arm-none-eabi-objcopy
  OBJDUMP := arm-none-eabi-objdump
  READELF := arm-none-eabi-readelf

  CFLAGS 	:= -nostartfiles -fno-builtin -g -O2 -mcpu=cortex-r5
  CPPFLAGS =
  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
endif


ifneq ("$(filter A55,$(ARCH))", "")
	TOOL_CHAINS := aarch64-elf-
  CC := $(TOOL_CHAINS)gcc
  LD := $(TOOL_CHAINS)ld
  AR := $(TOOL_CHAINS)ar
  OBJCOPY := $(TOOL_CHAINS)objcopy
  OBJDUMP := $(TOOL_CHAINS)objdump
  READELF := $(TOOL_CHAINS)readelf

 CFLAGS 	:= -march=armv8-a -mtune=cortex-a55  -c -DGCC -falign-functions=16 -falign-jumps=8 -falign-loops=8 -fomit-frame-pointer
# CFLAGS	+= -mgeneral-regs-only
 CFLAGS 	+= -fomit-frame-pointer  -fno-builtin -funroll-loops -O0 -fno-inline-functions -fno-inline -Wno-pointer-to-int-cast
 CFLAGS += -DAARCH64
 CFLAGS += -DA55
  CPPFLAGS =
#  LIBPATH  := -L $(TOP_DIR)/library/ -lgcc
  LIBPATH  := -L $(TOP_DIR)/library/
endif

ifeq ($(VMAADDR),)
	LD_VMAADDR :=
else
	LD_VMAADDR := -Ttext $(VMAADDR)
endif


ifeq ($(ARCH),A55)
  ARCH_DIR := arch/A55
endif

ifeq ($(ARCH),R5_SAFETY)
  ARCH_DIR := arch/R5_SAFETY
endif

ifeq ($(ARCH),R5_REALTIME)
  ARCH_DIR := arch/R5_REALTIME
endif

ifeq ($(ARCH),R5_SWITCH)
  ARCH_DIR := arch/R5_SWITCH
endif

ifeq ($(ARCH),R5_SWITCH_CPU0)
  ARCH_DIR := arch/R5_SWITCH_CPU0
endif

ifeq ($(ARCH),R5_SWITCH_CPU1)
  ARCH_DIR := arch/R5_SWITCH_CPU1
endif

ifeq ($(ARCH),R5_SWITCH_CPU2)
  ARCH_DIR := arch/R5_SWITCH_CPU2
endif

ifeq ($(ARCH),R5_SECURE)
  ARCH_DIR := arch/R5_SECURE
endif

ifeq ($(ARCH),R5_SOC)
  ARCH_DIR := arch/R5_SOC
endif

ifeq ($(ARCH),RISC_V)
  ARCH_DIR := arch/RISC_V
endif

ifeq ($(ARCH),M0)
  ARCH_DIR := arch/M0
endif

ifeq ($(ARCH),R5)
  ARCH_DIR := arch/R5
endif

ifneq ($(CHIP),)
	CFLAGS += -D CHIP_$(CHIP)
endif

ifneq ($(TEST_ENV),)
	CFLAGS += -D TEST_ENV_$(TEST_ENV)
endif

ifneq ($(MEM_LOG_START),)
	CFLAGS += -D LOG_TO_MEM
	CFLAGS += -D MEMORY_LOG_START=$(MEM_LOG_START)
	CFLAGS += -D MEMORY_LOG_END=$(MEM_LOG_END)
endif

ifneq ($(MAL_HEAP_START),)
	CFLAGS += -D MALLOC_HEAP
	CFLAGS += -D MALLOC_HEAP_START=$(MAL_HEAP_START)
	CFLAGS += -D MALLOC_HEAP_END=$(MAL_HEAP_END)
endif

ifneq ($(STACK_HEAD_ADDR),)
	CFLAGS += -D STACK_HEAD=$(STACK_HEAD_ADDR)
endif

ifneq ($(BST_UART_SYNC),0)
	CFLAGS += -D UART_XTOR_SYNC_ID=$(BST_UART_SYNC)
endif

ifneq ($(BST_A78_TEST),)
	CFLAGS += -D BST_A78_TEST
endif

#module_env += $(ARCH_DIR) library common
module_env += library common
CFLAGS += $(foreach n,$(module_test),-D moudle_test_$(n))

core ?= 0
ifeq ($(core), 0)
CFLAGS += -D CORE0_FLAG
endif
ifeq ($(core), 1)
CFLAGS += -D CORE1_FLAG
endif
ifeq ($(core), 2)
CFLAGS += -D CORE2_FLAG
endif
ifeq ($(core), 3)
CFLAGS += -D CORE3_FLAG
endif
ifeq ($(core), 4)
CFLAGS += -D CORE4_FLAG
endif
ifeq ($(core), 5)
CFLAGS += -D CORE5_FLAG
endif

################# Statistics timestamp configuration start ################
# Configure whether to enable the function of statistics code timestamp
CONFIG_STATISTICS_CODE_TIMESTAMP ?= n
# Configure whether to enable the function of statistics packet timestamp:
#
# The following configuration can only enable one at a time.
# can2eth_timestamp: enable timestamp for can2eth packet
# eth2can_timestamp: enable timestamp for eth2can packet
CONFIG_STATISTICS_PACKET_CAN2ETH_TIMESTAMP ?= n
CONFIG_STATISTICS_PACKET_ETH2CAN_TIMESTAMP ?= n
CONFIG_STATISTICS_PACKET_CAN2CAN_TIMESTAMP ?= n
################# Statistics timestamp configuration end #################

ifeq ($(CONFIG_STATISTICS_PACKET_CAN2ETH_TIMESTAMP), y)
ifeq ($(CONFIG_STATISTICS_PACKET_ETH2CAN_TIMESTAMP), y)
ifeq ($(CONFIG_STATISTICS_PACKET_CAN2CAN_TIMESTAMP), y)
$(error ERROR: Only one of CONFIG_STATISTICS_PACKET_CAN2ETH_TIMESTAMP or CONFIG_STATISTICS_PACKET_ETH2CAN_TIMESTAMP can be enabled at a time.)
endif
endif
endif

ifeq ($(CONFIG_STATISTICS_PACKET_CAN2ETH_TIMESTAMP), y)
CONFIG_STATISTICS_PACKET_TIMESTAMP = y
endif
ifeq ($(CONFIG_STATISTICS_PACKET_ETH2CAN_TIMESTAMP), y)
CONFIG_STATISTICS_PACKET_TIMESTAMP = y
endif
ifeq ($(CONFIG_STATISTICS_PACKET_CAN2CAN_TIMESTAMP), y)
CONFIG_STATISTICS_PACKET_TIMESTAMP = y
endif

ifeq ($(CONFIG_STATISTICS_CODE_TIMESTAMP), y)
CFLAGS += -DSTATISTICS_CODE_TIMESTAMP_ENABLE
endif
ifeq ($(CONFIG_STATISTICS_PACKET_TIMESTAMP), y)
CFLAGS += -DSTATISTICS_PACKET_TIMESTAMP_ENABLE
endif
ifeq ($(CONFIG_STATISTICS_PACKET_CAN2ETH_TIMESTAMP), y)
CFLAGS += -DSTATISTICS_PACKET_CAN2ETH_TIMESTAMP_ENABLE
else ifeq ($(CONFIG_STATISTICS_PACKET_ETH2CAN_TIMESTAMP), y)
CFLAGS += -DSTATISTICS_PACKET_ETH2CAN_TIMESTAMP_ENABLE
else ifeq ($(CONFIG_STATISTICS_PACKET_CAN2CAN_TIMESTAMP), y)
CFLAGS += -DSTATISTICS_PACKET_CAN2CAN_TIMESTAMP_ENABLE
endif

export TOP_DIR OBJ_DIR ELF_FILE CC LD OBJCOPY OBJDUMP READELF AR CPPFLAGS CFLAGS
export CONFIG_STATISTICS_CODE_TIMESTAMP CONFIG_STATISTICS_PACKET_TIMESTAMP

CFLAGS += -I $(PWD)/include
CFLAGS += -I $(PWD)/modules/ipc_msgbox/switch0-can-gateway-server/src-gen
CFLAGS += -I $(PWD)/modules/ipc_msgbox/switch0-canoe-client/src-gen
CFLAGS += -I $(PWD)/modules/ipc_msgbox/ipc_sem_layer
CFLAGS += -I $(PWD)/modules/ipc_msgbox/config
CFLAGS += -I $(PWD)/modules/ipc_msgbox/ipc_trans_layer/include
CFLAGS += -I $(PWD)/modules/ipc_msgbox/ipc_trans_layer/src
CFLAGS += -I $(PWD)/modules/ipc_msgbox/ipc_hw_layer/include
CFLAGS += -I $(PWD)/modules/ipc_msgbox/ipc_hw_layer/msgbx

all: $(module_env) $(module_test) ipc_msgbox final

final: FORCE
	cd $(OBJ_DIR) && $(LD) -T$(TOP_DIR)/hvte.lds $(notdir $(wildcard $(OBJ_DIR)/*.o)) $(LD_VMAADDR) $(LIBPATH) $(LDFLAGS) -o $(OUT_DIR)/$(ELF_FILE)
	cd $(OUT_DIR) && $(OBJCOPY) -O binary -S $(ELF_FILE) $(ELF_FILE).bin
	cd $(OUT_DIR) && $(OBJDUMP) -DS $(ELF_FILE) > $(ELF_FILE).dis
	cd $(OUT_DIR) && $(READELF) -h $(ELF_FILE)
ifneq ("$(filter A55,$(ARCH))", "")
		cd $(OUT_DIR) && $(OBJCOPY) -b 0 -i 4 --interleave-width 2 -I binary  $(ELF_FILE).bin a55_a.raw
		cd $(OUT_DIR) && $(OBJCOPY) -b 2 -i 4 --interleave-width 2 -I binary  $(ELF_FILE).bin a55_b.raw
endif
	@cd $(OUT_DIR) && cp -a $(ELF_FILE).bin ./zebu.raw
	@echo output file:$(OUT_DIR)/$(ELF_FILE)

ipc_msgbox: FORCE
	make -C ./modules/ipc_msgbox

$(module_test): FORCE
#	@echo $(INCLUDE_DIRS)
	make -C ./modules/$@


$(module_env): FORCE
ifeq ($(ARCH_DIR),)
	@echo ERROR: ARCH is invalid.
	@exit 1
endif
#ifneq ($(words $(module_test)), 20)
#	@echo ERROR: too many or too few test IPs\(only allow 20 test ip\).
#	@exit 1
#endif

	@rm -rf hvte.lds
ifeq ($(core), 0)
	@cp -a $(ARCH_DIR)/hvte.lds ./hvte.lds
endif

ifeq ($(core), 1)
	@cp -a $(ARCH_DIR)/hvte_core1.lds ./hvte.lds
endif

ifeq ($(core), 2)
	@cp -a $(ARCH_DIR)/hvte_core2.lds ./hvte.lds
endif

ifeq ($(core), 3)
	@cp -a $(ARCH_DIR)/hvte_core3.lds ./hvte.lds
endif

ifeq ($(core), 4)
	@cp -a $(ARCH_DIR)/hvte_core4.lds ./hvte.lds
endif

ifeq ($(core), 5)
	@cp -a $(ARCH_DIR)/hvte_core5.lds ./hvte.lds
endif
	
	@rm -rf ./common
	@mkdir -p ./common
	@cp -a $(ARCH_DIR)/* ./common/
	@rm -rf ./common/hvte.lds

#	@echo $(INCLUDE_DIRS)
	mkdir -p $(OUT_DIR) && mkdir -p $(OBJ_DIR)
	make -C $@

FORCE:

clean:
	rm -drf $(BUILD_DIR)
	rm -rf hvte.lds
	rm -rf common
	rm -rf build
	rm config.mk
